package blackjack.interfacetexto;

import blackjack.Baralho;
import blackjack.Carta;
import blackjack.Jogador;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Interface de Texto do jogo.
 * @author Guilherme de Lemos
 */
public class InterfaceTexto {
    private List<Jogador> jogadores;
    
    /**
     * Construtor padrão
     */
    public InterfaceTexto() {
        super();
        jogadores = new ArrayList<Jogador>();
    }
    
    /**
     * Inicia o jogo em modo texto
     */
    public void iniciarJogo() {
        imprimirIdentificacao();
        if(this.jogadores.isEmpty()) {
            registroJogadores();
            //menuJogador();
        }
        menuPrincipal();
    }
    
    /**
     * Imprime o menu principal
     */
    protected void imprimirMenuPrincipal() {
        System.out.println("\n#==============================");
        System.out.println("# Menu Principal");
        System.out.println("1- Configurar Jogadores");
        System.out.println("2- Iniciar Jogo");
        System.out.println("0- Sair\n");
    }
    
    /**
     * Inicia o menu principal
     */
    protected void menuPrincipal() {
        imprimirMenuPrincipal();
        try {
            System.out.print("Informe uma opção: ");
            int opcao = Integer.parseInt(lerTeclado());
            while(opcao != 0) {
                switch(opcao) {
                    case 1:
                        menuJogador();
                        imprimirMenuPrincipal();
                        System.out.print("Informe uma opção: ");
                        opcao = Integer.parseInt(lerTeclado());
                        break;
                    case 2:
                        jogar();
                        imprimirMenuPrincipal();
                        System.out.print("Informe uma opção: ");
                        opcao = Integer.parseInt(lerTeclado());
                        break;
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Inicia o jogo de cartas
     */
    protected void jogar() {
        Baralho baralho = new Baralho();
        System.out.println("\n#==============================");
        System.out.println("Iniciando o jogo");
        
        if(jogadores.isEmpty()) {
            System.out.println("Não existem jogadores registrados!");
            return;
        }
        
        listarJogadores();
        System.out.println("");
        
        for(Jogador jogadorVez: jogadores) {
            jogadorVez.limparPontos();
            System.out.println("Vez do(a) jogador(a): " + jogadorVez.getNome());
            
            // RODADA
            imprimirMenuJogo();
            int opcao = lerOpcaoMenu("O que você deseja fazer? ");
            if(opcao == 0) {
                System.out.println("Encerrando partida");
                jogadorVez.acrescentarDerrota();
                imprimirResumoJogo();
                return;
            }
            while(opcao == 1) {
                switch(opcao) {
                    case 1: // puxar carta
                        Carta cartaPuxada = baralho.puxar();
                        System.out.println("Carta puxada: " + cartaPuxada);
                        
                        
                        
                        jogadorVez.acrescentarPontons(cartaPuxada.getValor());
                        System.out.println("Total de pontos: " + jogadorVez.getQtdePontos());
                        
                        imprimirMenuJogo();
                        opcao = lerOpcaoMenu("O que você deseja fazer? ");
                        
                        break;
                    case 2:
                        System.out.println("Passar vez");
                        imprimirPontosJogador(jogadorVez);
                        opcao = 2;
                        break;
                    case 0:
                        System.out.println("Encerrando partida");
                        jogadorVez.acrescentarDerrota();
                        imprimirResumoJogo();
                        return;
                }
            }
        }
        averiguarVencedorPartida();
        imprimirResumoJogo();
    }
    
    protected void averiguarVencedorPartida() {
        Jogador jogador1 = null;
        Jogador vencedor = null;
        for(Jogador jogador2: jogadores) {
            if(jogador1 == null) {
                jogador1 = jogador2;
            } else {
                if(jogador2.getQtdePontos() == jogador1.getQtdePontos()) {
                    jogador1.acrescentarEmpate();
                    jogador2.acrescentarEmpate();
                } else if(jogador2.getQtdePontos() > jogador1.getQtdePontos()) {
                    jogador1.acrescentarDerrota();
                    jogador2.acrescentarVitoria();
                    vencedor = jogador2;
                } else {
                    jogador1.acrescentarVitoria();
                    jogador2.acrescentarDerrota();
                    vencedor = jogador1;
                }
            }
        }
        System.out.println("O vencedor dessa partido foi: " + vencedor);
    }
    
    /**
     * Imprime os pontos do jogador para a partida.
     * @param jogador Jogador
     */
    protected void imprimirPontosJogador(Jogador jogador) {
        System.out.println(jogador.getNome() + " fez " 
                + jogador.getQtdePontos() + " pontos.");
    }
    
    protected void imprimirResumoJogo() {
        for(Jogador j: jogadores) {
            System.out.println(j);
        }
    }
    
    protected int lerOpcaoMenu(String mensagem) {
        System.out.print(mensagem);
        int opcao = 0;
        try {
            opcao = Integer.parseInt(lerTeclado());
        } catch(NumberFormatException e) {
            System.out.println("Opção inválida!");
            lerOpcaoMenu(mensagem);
        }
        return opcao;
    }
    
    /**
     * Imprime o menu do Jogo.
     */
    protected void imprimirMenuJogo() {
        System.out.println("1- Puxar carta");
        System.out.println("2- Passar Vez");
        System.out.println("0- Desistir");
    }
    
    /**
     * Imprime o menu do Jogador.
     */
    protected void imprimirMenuJogador() {
        System.out.println("\n#==============================");
        System.out.println("# Menu do Jogador");
        System.out.println("1- Listar jogadores");
        System.out.println("2- Criar jogador");
        System.out.println("3- Remover jogador");
        System.out.println("0- Menu Principal\n");
    }
    
    /**
     * Exibe o menu do jogador na saída principal.
     */
    protected void menuJogador() {
        try {
            boolean lerOpcao = true;
            while(lerOpcao) {
                imprimirMenuJogador();
                System.out.print("Informe uma opção: ");
                switch(Integer.parseInt(lerTeclado())) {
                    case 1:
                        //System.out.println("1- Listar jogadores");
                        listarJogadores();
                        break;
                    case 2:
                        //System.out.println("2- Criar jogador");
                        registroJogadores();
                        break;
                    case 3:
                        //System.out.println("3- Remover jogador");
                        removerJogador();
                        break;
                    case 0:
                        //System.out.println("0- Menu Principal");
                        lerOpcao = false;
                        break;
                } // switch
            } // while
        } catch(NumberFormatException e) {
            System.out.println("Opção inválida!");
            menuJogador();
        } catch(Exception e) {
            e.printStackTrace();
        } // try-catch
    }
    
    /**
     * Cria jogadores com base no que o usuário informar.
     */
    protected void registroJogadores() {
        System.out.println("# Registro de Jogadores");
        
        if(jogadores.size() >= 2) {
            System.out.println("Atingido o limite de jogadores por partida!");
            return;
        }
        System.out.print("Informe o nome do jogador: ");
        String nome = lerTeclado();
        Jogador jogador = new Jogador();
        jogador.setNome(nome);
        this.jogadores.add(jogador);
    }
    
    /**
     * Imprime os jogadores na saída padrão.
     */
    protected void listarJogadores() {
        if(jogadores.isEmpty()) {
            System.out.println("Não existem jogadores registrados.");
        }
        for(int i=0; i<jogadores.size();i++) {
            System.out.println("#" + (i+1) + " " + jogadores.get(i));
        }
    }
    
    /**
     * Remove um jogador
     */
    protected void removerJogador() {
        try {
            listarJogadores();
            System.out.print("Informe o número do jogador a ser removido: ");
            int opcao = Integer.parseInt(lerTeclado());
            if(opcao <= 0 || opcao > (jogadores.size()) ) {
                System.out.println("Jogador inválido!");
                removerJogador();
            } else {
                jogadores.remove(opcao-1);
            }
        } catch(NumberFormatException e) {
            System.out.println("Jogador inválido!");
            removerJogador();
        }
    }
    
    /**
     * Realiza leitura do teclado na entrada padrão.
     * @return leitura do teclado
     */
    protected String lerTeclado() {
        BufferedReader leitor = new BufferedReader(new InputStreamReader(System.in));
        try {
            return leitor.readLine();
        } catch(IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * Imprime a identificação do Jogo na saída padrão.
     */
    public static void imprimirIdentificacao() {
        System.out.println("Jogo Blackjack");
        System.out.println("Esse é um exemplo didático de programação "
                + "utilizando Java");
        System.out.println("Disponível em: "
                + "http://code.google.com/p/glemos-java/");
        System.out.println("Desenvolvido por Guilherme de Lemos");
        System.out.println("==============================");
    }
}
